class M3U8Player {
    constructor() {
        this.urlInput = document.getElementById('m3u8-url');
        this.playBtn = document.getElementById('play-btn');
        this.scanBtn = document.getElementById('scan-btn');
        this.videoPlayer = document.getElementById('video-player');
        this.loading = document.getElementById('loading');
        this.urlList = document.getElementById('url-list');
        this.urlCount = document.querySelector('.url-count');
        this.hls = null;
        this.tsList = document.getElementById('ts-list'); // 初始化 tsList
        this.adRemoveSwitch = document.getElementById('ad-remove-switch');

        this.hlsConfig = {
            maxBufferLength: 30,
            maxMaxBufferLength: 600,
            enableWorker: true,
            lowLatencyMode: true,
            backBufferLength: 90
        };

        this.init();
        // 页面加载时自动扫描剪切板
        this.autoScanClipboard();
    }
    
    init() {
        if (!Hls.isSupported()) {
            alert('当前浏览器不支持该视频格式，请使用 Chrome 或 Firefox 最新版本');
            return;
        }
        this.playBtn.addEventListener('click', () => this.handlePlay());
        this.scanBtn.addEventListener('click', () => this.handleScan());
        this.urlList.addEventListener('click', (e) => this.handleUrlSelect(e));
    }
    
    async autoScanClipboard() {
        try {
            const clipboardText = await navigator.clipboard.readText();
            const urls = this.findM3u8Urls(clipboardText);
            if (urls.length > 0) {
                this.updateUrlList(urls);
            }
        } catch (error) {
            console.error('自动扫描剪切板失败:', error);
        }
    }
    
    async handlePlay() {
        const url = this.urlInput.value.trim();
        if (!url) {
            alert('请输入m3u8地址');
            return;
        }
        
        try {
            this.showLoading();
            const m3u8Content = await this.fetchM3U8(url);
            const { realContent, realUrl } = await this.resolveRealM3U8(m3u8Content, url);
            const { segments, params } = this.parseM3U8(realContent, realUrl);
            
            let finalSegments = segments;
            // 根据开关状态决定是否去广告
            if (this.adRemoveSwitch.checked) {
                const adSegments = segments.filter(seg => seg.isAd);
                const nonAdSegments = segments.filter(seg => !seg.isAd);
                finalSegments = nonAdSegments.length > 0 ? nonAdSegments : segments;
            }
            
            if (finalSegments.length === 0) {
                throw new Error('未找到可用的视频片段');
            }
            
            this.playVideo(finalSegments, params);
        } catch (error) {
            console.error('播放失败:', error);
            alert(`视频播放失败: ${error.message}`);
        } finally {
            this.hideLoading();
        }
    }
    
    async fetchM3U8(url) {
        const response = await fetch(url);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.text();
    }
    
    async resolveRealM3U8(content, baseUrl) {
        const lines = content.split('\n');
        const basePath = new URL(baseUrl).href.substring(0, baseUrl.lastIndexOf('/') + 1);
        
        // 查找最高码率的子M3U8
        let maxBandwidth = 0;
        let targetUrl = '';
        
        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trim();
            if (line.startsWith('#EXT-X-STREAM-INF')) {
                const bandwidth = parseInt(line.match(/BANDWIDTH=(\d+)/)?.[1] || '0');
                if (bandwidth > maxBandwidth) {
                    maxBandwidth = bandwidth;
                    const nextLine = lines[i + 1]?.trim();
                    if (nextLine && !nextLine.startsWith('#')) {
                        targetUrl = nextLine.startsWith('http') ? nextLine : new URL(nextLine, basePath).href;
                    }
                }
            }
        }
        
        if (targetUrl) {
            const subContent = await this.fetchM3U8(targetUrl);
            return { realContent: subContent, realUrl: targetUrl };
        }
        
        return { realContent: content, realUrl: baseUrl };
    }
    
    parseM3U8(content, baseUrl) {
        const lines = content.split('\n');
        const basePath = new URL(baseUrl).href.substring(0, baseUrl.lastIndexOf('/') + 1);
        const segments = [];
        const params = {
            version: 3,
            targetDuration: 10,
            mediaSequence: 0,
            endList: true
        };
        
        let currentDuration = 0;
        let lastSegmentNumber = null;
        let currentPrefix = null;
    
        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trim();
    
            // 解析M3U8参数
            if (line.startsWith('#EXT-X-VERSION:')) {
                params.version = parseInt(line.split(':')[1]);
            } else if (line.startsWith('#EXT-X-TARGETDURATION:')) {
                params.targetDuration = parseFloat(line.split(':')[1]);
            } else if (line.startsWith('#EXT-X-MEDIA-SEQUENCE:')) {
                params.mediaSequence = parseInt(line.split(':')[1]);
            } else if (line.startsWith('#EXTINF:')) {
                currentDuration = parseFloat(line.split(':')[1]);
            } else if (line.endsWith('.ts')) {
                const url = line.startsWith('http') ? line : new URL(line, basePath).href;
                const filename = url.split('/').pop();
                const match = filename.match(/^([a-f0-9]+?)(\d+)\.ts$/);
    
                if (match) {
                    const [, prefix, number] = match;
                    const segmentNumber = parseInt(number);
                    const isAd = !(lastSegmentNumber === null || 
                        (segments.length > 0 && 
                         segments[segments.length - 1].prefix === prefix && 
                         segmentNumber === lastSegmentNumber + 1));
    
                    segments.push({
                        url,
                        duration: currentDuration,
                        prefix,
                        number: segmentNumber,
                        isAd: isAd
                    });
    
                    if (!isAd) {
                        lastSegmentNumber = segmentNumber;
                        currentPrefix = prefix;
                    }
                }
            }
        }
    
        return { segments, params };
    }
    
    playVideo(segments, params) {
        if (this.hls) {
            this.hls.destroy();
        }
        if (this.tsList) { 
            this.tsList.innerHTML = '';
        }
    
        // 创建本地M3U8
        let content = '#EXTM3U\n';
        content += `#EXT-X-VERSION:${params.version}\n`;
        content += `#EXT-X-TARGETDURATION:${Math.ceil(params.targetDuration)}\n`;
        content += `#EXT-X-MEDIA-SEQUENCE:${params.mediaSequence}\n`;
    
        if (this.tsList) { 
            segments.forEach((segment, index) => {
                content += `#EXTINF:${segment.duration.toFixed(3)},\n`;
                content += segment.url + '\n';
    
                const li = document.createElement('li');
                li.textContent = `序号: ${index + 1}, 文件: ${segment.url.split('/').pop()}`;
                li.addEventListener('click', () => {
                    this.jumpToSegment(index, segments);
                });
                this.tsList.appendChild(li);
            });
        }
    
        if (params.endList) {
            content += '#EXT-X-ENDLIST\n';
        }
    
        // 创建播放器
        const blob = new Blob([content], { type: 'application/vnd.apple.mpegurl' });
        const blobUrl = URL.createObjectURL(blob);
    
        this.hls = new Hls({
            debug: false,
            enableWorker: true,
            lowLatencyMode: true,
            // 增加缓冲区配置优化卡顿
            maxBufferLength: 60,
            maxMaxBufferLength: 1200,
            backBufferLength: 180
        });
    
        // 监听片段加载完成事件，高亮当前播放的 TS 文件
        this.hls.on(Hls.Events.FRAG_LOADED, (event, data) => {
            const currentFragIndex = data.frag.sn - params.mediaSequence;
            if (currentFragIndex >= 0 && currentFragIndex < segments.length) {
                this.highlightCurrentTS(currentFragIndex);
            }
        });
    
        this.hls.on(Hls.Events.ERROR, (event, data) => {
            if (data.fatal) {
                switch (data.type) {
                    case Hls.ErrorTypes.NETWORK_ERROR:
                        this.hls.startLoad();
                        break;
                    case Hls.ErrorTypes.MEDIA_ERROR:
                        this.hls.recoverMediaError();
                        break;
                    default:
                        this.hls.destroy();
                        URL.revokeObjectURL(blobUrl);
                        break;
                }
            }
        });
    
        this.hls.loadSource(blobUrl);
        this.hls.attachMedia(this.videoPlayer);
    
        this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
            console.log(`开始播放，共 ${segments.length} 个片段`);
            this.videoPlayer.play().catch(error => {
                console.error('播放失败:', error);
            });
        });
    }

    // 新增跳转方法
    jumpToSegment(index, segments) {
        if (!this.hls || !this.videoPlayer) return;

        // 计算跳转的时间点
        let seekTime = 0;
        for (let i = 0; i < index; i++) {
            seekTime += segments[i].duration;
        }

        // 跳转到指定时间点
        this.videoPlayer.currentTime = seekTime;
        this.videoPlayer.play().catch(error => {
            console.error('跳转后播放失败:', error);
        });
    }

    // 新增高亮方法
    highlightCurrentTS(index) {
        if (!this.tsList) return;
        const lis = this.tsList.querySelectorAll('li');
        lis.forEach((li, i) => {
            if (i === index) {
                li.classList.add('active'); // 假设 active 类用于高亮
            } else {
                li.classList.remove('active');
            }
        });
    }
    
    showLoading() {
        this.loading.classList.remove('hidden');
    }
    
    hideLoading() {
        this.loading.classList.add('hidden');
    }
    
    async handleScan() {
        this.showLoading();
        try {
            const urls = new Set();
            
            // 扫描剪切板
            const clipboardText = await navigator.clipboard.readText();
            this.findM3u8Urls(clipboardText).forEach(url => urls.add(url));
            
            // 更新URL列表
            this.updateUrlList(Array.from(urls));
        } catch (error) {
            console.error('扫描失败:', error);
            alert('扫描失败: ' + error.message);
        } finally {
            this.hideLoading();
        }
    }
    
    findM3u8Urls(text) {
        // 匹配格式：名称$m3u8文件地址
        const urlPattern = /([^$\n]+)\$(https?:\/\/[^\s<>"']+?\.m3u8(?:[^\s<>"']*)?)/g;
        const results = [];
        let match;
        
        while ((match = urlPattern.exec(text)) !== null) {
            results.push({
                name: match[1].trim(),
                url: match[2].trim()
            });
        }
        
        // 如果没有找到带$符号的格式，尝试匹配单独的m3u8地址
        if (results.length === 0) {
            const simplePattern = /(https?:\/\/[^\s<>"']+?\.m3u8(?:[^\s<>"']*)?)/g;
            while ((match = simplePattern.exec(text)) !== null) {
                results.push({
                    name: this.extractNameFromUrl(match[1]),
                    url: match[1].trim()
                });
            }
        }
        
        return results;
    }
    
    extractNameFromUrl(url) {
        try {
            // 尝试从URL中提取文件名
            const urlObj = new URL(url);
            const pathSegments = urlObj.pathname.split('/');
            const lastSegment = pathSegments[pathSegments.length - 1];
            
            // 如果最后一段包含文件名特征，返回它
            if (lastSegment && lastSegment.length > 8) {
                const dateMatch = url.match(/\/(\d{8})\//);
                if (dateMatch) {
                    return this.formatDate(dateMatch[1]) + '期';
                }
                return lastSegment.replace(/\.m3u8.*$/, '');
            }
            
            // 否则返回域名
            return urlObj.hostname;
        } catch (e) {
            return '未命名视频';
        }
    }
    
    formatDate(dateStr) {
        if (dateStr.length === 8) {
            return `${dateStr.slice(0,4)}${dateStr.slice(4,6)}${dateStr.slice(6,8)}`;
        }
        return dateStr;
    }
    
    updateUrlList(urls) {
        this.urlList.innerHTML = '';
        this.urlCount.textContent = `(${urls.length})`;
        
        urls.forEach(({name, url}) => {
            const li = document.createElement('li');
            li.dataset.url = url;
            
            // 创建名称元素
            const nameSpan = document.createElement('span');
            nameSpan.className = 'url-name';
            nameSpan.textContent = name || '未命名视频';
            
            // 创建URL元素
            const urlSpan = document.createElement('span');
            urlSpan.className = 'url-link';
            urlSpan.textContent = url;
            
            // 添加到列表项
            li.appendChild(nameSpan);
            li.appendChild(urlSpan);
            
            if (url === this.urlInput.value) {
                li.classList.add('active');
            }
            
            this.urlList.appendChild(li);
        });
    }
    
    handleUrlSelect(e) {
        const li = e.target.closest('li');
        if (!li) return;
        
        // 更新选中状态
        this.urlList.querySelectorAll('li').forEach(item => item.classList.remove('active'));
        li.classList.add('active');
        
        // 更新输入框
        this.urlInput.value = li.dataset.url;
        
        // 自动播放
        this.handlePlay();
    }
}

document.addEventListener('DOMContentLoaded', () => new M3U8Player());